package com.gitee.kenewstar.migration.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gitee.kenewstar.migration.constants.Const;
import com.gitee.kenewstar.migration.entity.CodeRule;
import com.gitee.kenewstar.migration.entity.CodeRuleDetail;
import com.gitee.kenewstar.migration.entity.CodeRuleDist;
import com.gitee.kenewstar.migration.entity.CodeRuleTl;
import com.gitee.kenewstar.migration.mapper.CodeRuleDetailMapper;
import com.gitee.kenewstar.migration.mapper.CodeRuleDistMapper;
import com.gitee.kenewstar.migration.mapper.CodeRuleMapper;
import com.gitee.kenewstar.migration.mapper.CodeRuleTlMapper;
import com.gitee.kenewstar.migration.service.CodeRuleService;
import com.gitee.kenewstar.migration.util.Util;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author kenewstar
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class CodeRuleServiceImpl implements CodeRuleService {

    private final CodeRuleMapper codeRuleMapper;
    private final CodeRuleTlMapper codeRuleTlMapper;
    private final CodeRuleDistMapper codeRuleDistMapper;
    private final CodeRuleDetailMapper codeRuleDetailMapper;


    @Override
    @DS(Const.DEV)
    public List<CodeRule> devSelectCodeRuleList(List<CodeRule> list) {
        if (CollUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        QueryWrapper<CodeRule> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("rule_code", list.stream().map(CodeRule::getRuleCode).collect(Collectors.toSet()));
        queryWrapper.in(Const.TENANT_ID, list.stream().map(CodeRule::getTenantId).collect(Collectors.toSet()));
        List<CodeRule> codeRuleList = this.codeRuleMapper.selectList(queryWrapper);

        final Map<String, Long> map = list.stream().collect(Collectors.toMap(x -> x.getRuleCode() + "-" + x.getTenantId(), CodeRule::getTenantId));
        codeRuleList = codeRuleList.stream().filter(x -> Objects.nonNull(map.get(x.getRuleCode() + "-" + x.getTenantId()))).collect(Collectors.toList());

        return codeRuleList;
    }

    @Override
    @DS(Const.DEV)
    public List<CodeRuleTl> devSelectCodeRuleTl(List<Long> ruleIds) {
        if (CollUtil.isEmpty(ruleIds)) {
            return Collections.emptyList();
        }
        QueryWrapper<CodeRuleTl> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("rule_id", ruleIds);
        return this.codeRuleTlMapper.selectList(queryWrapper);
    }

    @Override
    @DS(Const.DEV)
    public List<CodeRuleDist> devSelectCodeRuleDist(List<Long> ruleIds) {
        if (CollUtil.isEmpty(ruleIds)) {
            return Collections.emptyList();
        }
        QueryWrapper<CodeRuleDist> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("rule_id", ruleIds);
        return this.codeRuleDistMapper.selectList(queryWrapper);
    }

    @Override
    @DS(Const.DEV)
    public List<CodeRuleDetail> devSelectCodeRuleDetail(List<Long> distIds) {
        if (CollUtil.isEmpty(distIds)) {
            return Collections.emptyList();
        }
        QueryWrapper<CodeRuleDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("rule_dist_id", distIds);
        return this.codeRuleDetailMapper.selectList(queryWrapper);
    }

    @Override
    @DS(Const.UAT)
    @Transactional(rollbackFor = Exception.class)
    public void uatInsertCodeRule(List<CodeRule> list) {
        list.forEach(x -> x.setTenantId(Util.getTenant(x.getTenantId())));
        list.forEach(this.codeRuleMapper::insert);
    }

    @Override
    @DS(Const.UAT)
    @Transactional(rollbackFor = Exception.class)
    public void uatInsertCodeRuleTl(List<CodeRuleTl> list) {
        list.forEach(x -> x.setTenantId(Util.getTenant(x.getTenantId())));
        list.forEach(this.codeRuleTlMapper::insert);
    }

    @Override
    @DS(Const.UAT)
    @Transactional(rollbackFor = Exception.class)
    public void uatInsertCodeRuleDist(List<CodeRuleDist> list) {
        list.forEach(x -> x.setTenantId(Util.getTenant(x.getTenantId())));
        list.forEach(this.codeRuleDistMapper::insert);
    }

    @Override
    @DS(Const.UAT)
    @Transactional(rollbackFor = Exception.class)
    public void uatInsertCodeRuleDetail(List<CodeRuleDetail> list) {
        list.forEach(x -> x.setTenantId(Util.getTenant(x.getTenantId())));
        list.forEach(this.codeRuleDetailMapper::insert);
    }



}
